﻿using System;
using System.IO;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using Google.GData.YouTube;
using uTube.Core.Extensions;
using uTube.Core.DataTypes.PrevalueEditors;
using uTube.Core.Properties;
using umbraco.cms.businesslogic.datatype;

namespace uTube.Core.DataTypes.YouTubeVideoPicker
{
	public class YTVP_PrevalueEditor : AbstractJsonPrevalueEditor
	{
		/// <summary>
		/// TextBox control for the application name.
		/// </summary>
		private TextBox txtApplicationName;

		/// <summary>
		/// TextBox control for the developer key.
		/// </summary>
		private TextBox txtDeveloperKey;

		/// <summary>
		/// TextBox control for the maximum number of videos.
		/// </summary>
		private TextBox txtMaxVideos;

		/// <summary>
		/// TextBox control for the YouTube query.
		/// </summary>
		private TextBox txtQuery;

		/// <summary>
		/// DropDownList control for the safe search.
		/// </summary>
		private DropDownList ddlSafeSearch;

		/// <summary>
		/// Initializes a new instance of the <see cref="YTVP_PrevalueEditor"/> class.
		/// </summary>
		/// <param name="dataType">Type of the data.</param>
		public YTVP_PrevalueEditor(BaseDataType dataType)
			: base(dataType, DBTypes.Ntext)
		{
		}

		/// <summary>
		/// Populates the drop down list with enum.
		/// </summary>
		/// <param name="enumerator">The enumerator.</param>
		/// <param name="dropDownList">The drop down list.</param>
		private void PopulateDropDownListWithEnum(Type enumerator, DropDownList dropDownList)
		{
			if (dropDownList != null)
			{
				dropDownList.Items.Clear();

				foreach (var value in Enum.GetValues(enumerator))
				{
					ListItem item = new ListItem(Enum.GetName(enumerator, value), value.ToString());
					dropDownList.Items.Add(item);
				}
			}
		}

		/// <summary>
		/// Saves the data-type PreValue options.
		/// </summary>
		public override void Save()
		{
			// prep the option values
			int maxVideos = 0;
			int.TryParse(this.txtMaxVideos.Text, out maxVideos);

			string applicationName = this.txtApplicationName.Text;
			if (string.IsNullOrEmpty(applicationName))
			{
				applicationName = Settings.Default.ApplicationName;
			}

			string developerKey = this.txtDeveloperKey.Text;
			if (string.IsNullOrEmpty(developerKey))
			{
				developerKey = Settings.Default.DeveloperKey;
			}

			// set the options
			var options = new YTVP_Options()
			{
				ApplicationName = applicationName,
				DeveloperKey = developerKey,
				MaxVideos = maxVideos,
				Query = this.txtQuery.Text,
				SafeSearch = this.ddlSafeSearch.SelectedIndex
			};

			// save the options as JSON
			this.SaveAsJson(options);
		}

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Init"/> event.
		/// </summary>
		/// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			this.EnsureChildControls();
		}

		/// <summary>
		/// Creates child controls for this control
		/// </summary>
		protected override void CreateChildControls()
		{
			base.CreateChildControls();

			// set-up child controls
			this.txtApplicationName = new TextBox() { ID = "txtApplicationName", CssClass = "guiInputText umbEditorTextField" };
			this.txtDeveloperKey = new TextBox() { ID = "txtDeveloperKey", CssClass = "guiInputText umbEditorTextField" };
			this.txtMaxVideos = new TextBox() { ID = "txtMaxVideos", CssClass = "guiInputText", Width = 45 };
			this.txtQuery = new TextBox() { ID = "txtQuery", CssClass = "guiInputText umbEditorTextField" };
			this.ddlSafeSearch = new DropDownList() { ID = "ddlSafeSearch" };

			// populate the controls
			this.PopulateDropDownListWithEnum(typeof(YouTubeQuery.SafeSearchValues), this.ddlSafeSearch);

			// add the child controls
			this.Controls.AddPrevalueControls(this.txtApplicationName, this.txtDeveloperKey, this.txtMaxVideos, this.txtQuery, this.ddlSafeSearch);
		}

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Load"/> event.
		/// </summary>
		/// <param name="e">The <see cref="T:System.EventArgs"/> object that contains the event data.</param>
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			// get PreValues, load them into the controls.
			var options = this.GetPreValueOptions<YTVP_Options>();

			// if the options are null, then load the defaults
			if (options == null)
			{
				options = new YTVP_Options(true);
			}

			// set the values
			this.txtApplicationName.Text = options.ApplicationName;
			this.txtDeveloperKey.Text = options.DeveloperKey;
			this.txtMaxVideos.Text = options.MaxVideos.ToString();
			this.txtQuery.Text = options.Query;
			this.ddlSafeSearch.SelectedIndex = options.SafeSearch;
		}

		/// <summary>
		/// Renders the contents of the control to the specified writer. This method is used primarily by control developers.
		/// </summary>
		/// <param name="writer">A <see cref="T:System.Web.UI.HtmlTextWriter"/> that represents the output stream to render HTML content on the client.</param>
		protected override void RenderContents(HtmlTextWriter writer)
		{
			// add property fields
			writer.AddPrevalueHeading("Video Source Settings");
			writer.AddPrevalueRow("Max videos:", "The maximum number of videos to retrieve. <strong>Maximum number is 50 videos.</strong>", this.txtMaxVideos);
			writer.AddPrevalueRow("Query:", "Specifies the search query term; Searches all video metadata for videos matching the term, including titles, keywords, descriptions, authors' usernames, and categories.", this.txtQuery);
			writer.AddPrevalueRow("Safe search:", "Safe Search indicates whether the search results should include restricted content as well as standard content.", this.ddlSafeSearch);

			writer.AddPrevalueHeading("YouTube API Settings");
			writer.AddPrevalueRow("", "If you wish to use your own YouTube application name and developer key, you can do so here.");
			writer.AddPrevalueRow("Application Name:", this.txtApplicationName);
			writer.AddPrevalueRow("Developer Key:", this.txtDeveloperKey);
		}
	}
}
